package com.foreveross.proxyip.infra.utils;

import java.io.InputStream;
import java.util.Properties;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * propertis文件读取工具类
 * 
 * @author fb
 */
public class PropertiesUtil {

	private static Logger logger = LoggerFactory.getLogger(PropertiesUtil.class);

	// 配制文件锁
	private static ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

	/**
	 * 获取工程配制文件参数对象
	 * 
	 * @return string
	 */
	public static Properties getProperties(String fileName, CacheUtils.CacheInstance cacheEm) {
		CacheUtils cache = CacheUtils.newInstance().instanceCache(cacheEm);
		String key = "properties_" + fileName + "_cache";
		InputStream inStream = null;
		Properties properties = cache.get(key);

		// 加读锁
		rwl.readLock().lock();
		if (properties == null) {

			// 当缓存为空时读锁升为写锁
			rwl.readLock().unlock();
			rwl.writeLock().lock();

			if (properties == null) {
				properties = new Properties();
				
				try {
					inStream = PropertiesUtil.class.getClassLoader().getResourceAsStream(fileName + ".properties");

					properties.load(inStream);
					cache.put(key, properties);

					logger.debug("读取配制放入缓存:，key: {}, value: {}" , new Object[]{key, properties});
				} catch (Exception e) {
					logger.error(e.toString());
				} finally {
					try {
						if (inStream != null) {
							inStream.close();
						}
					} catch (Exception e) {
						logger.error("close inputStream error", e);
					}
				}
			}

			// 完成put操作后，恢复成读锁
			rwl.writeLock().unlock();
			rwl.readLock().lock();
		} else {
			logger.debug("从缓存中命中: key:{},value:{}" , new Object[]{key, properties});
		}
		
		// 释放读锁
		rwl.readLock().unlock();

		return properties;
	}
	
	/**
	 * 获取XML参数
	 * 
	 * @param fileName
	 *            配制文件名
	 * @param key
	 *            要获取配制文件中参数的key
	 * 
	 * @return
	 */
	public static Properties getXml(String fileName, CacheUtils.CacheInstance cacheEm) {
		CacheUtils cache = CacheUtils.newInstance().instanceCache(cacheEm);
		String key = "xml_" + fileName + "_cache";
		InputStream inStream = null;
		Properties properties = cache.get(key);

		logger.debug("xml配制文件路径：{}", fileName);
		
		// 加读锁
		rwl.readLock().lock();
		if (properties == null) {
			// 当缓存为空时读锁升为写锁
			rwl.readLock().unlock();
			rwl.writeLock().lock();

			if (properties == null) {
				properties = new Properties();
				try {
					inStream = PropertiesUtil.class.getClassLoader().getResourceAsStream(fileName + ".xml");
					properties.loadFromXML(inStream);
					cache.put(key, properties);
					logger.debug("读取配制放入缓存:，key: {}, value: {}" , new Object[]{key, properties});
				} catch (Exception e) {
					logger.error(e.toString());
				} finally {
					try {
						inStream.close();
					} catch (Exception e) {
						logger.error("close inputStream error", e);
					}
				}
			}
			// 完成put操作后，恢复成读锁
			rwl.writeLock().unlock();
			rwl.readLock().lock();
		} else {
			logger.debug("从缓存中命中: key:{},value:{}" , new Object[]{key, properties});
		}
		// 释放读锁
		rwl.readLock().unlock();
		
		return properties;
	}

	/**
	 * 获取工程配制文件参数
	 * 
	 * @param fileName
	 *            配制文件名
	 * @param key
	 *            要获取配制文件中参数的key
	 * 
	 * @return
	 */
	public static String getPropertiesValue(String fileName, String key,  CacheUtils.CacheInstance cacheEm) {
		Properties properties = getProperties(fileName, cacheEm);

		return properties.getProperty(key);
	}
	
	/**
	 * 默认系统配制读取
	 * 
	 * @param key
	 * @return
	 */
	public static String getSystemValue(String key) {
		Properties properties = getProperties("META-INF/props/system-config", CacheUtils.CacheInstance.SYSTEM);

		return properties.getProperty(key);
	}

	/**
	 * 获取XML参数
	 * 
	 * @param fileName
	 *            配制文件名
	 * @param key
	 *            要获取配制文件中参数的key
	 * 
	 * @return
	 */
	public static String getXmlValue(String fileName, String element, CacheUtils.CacheInstance cacheEm) {
		Properties properties = getXml(fileName, cacheEm);

		return properties.getProperty(element);
	}
}
